package fr.utt.lo02.CrazyEights.view;


import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import fr.utt.lo02.CrazyEights.model.Game;
import fr.utt.lo02.CrazyEights.model.Game.EndMethod;

/**
 * Represents the dialog to set the game settings
 * @author Jeremy
 *
 */
public class GameSettingsDialog extends JDialog{
	private static final long serialVersionUID = 1L;
	private JLabel labelNbOfPlayers;
	private JLabel labelNbHumanPlayers;
	private JLabel labelNbOfCardsByPlayer;
	private JLabel labelEndMethod;
	private JComboBox nbPlayers;
	private JComboBox nbHumanPlayers;
	private JComboBox nbOfCardsByPlayer;
	private JComboBox endMethod;
	private JButton start;
	private JButton cancel;
	private MainWindow window;
	
	/**
	 * Represents a dialog to set the game settings
	 * @param window The parent window
	 */
	public GameSettingsDialog(MainWindow window){
		super(window,"Game Settings",true);
		this.setSize(550, 270);
		this.setLocationRelativeTo(null);
		this.setResizable(false);
		this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
		
		this.window = window;
		labelNbOfPlayers = new JLabel("Number of players");
		nbPlayers = new JComboBox();
		for(int i=2;i<9;i++){
			nbPlayers.addItem(i);
		}
		
		labelNbHumanPlayers = new JLabel("Number of human players");
		nbHumanPlayers = new JComboBox();
		for(int i=1;i<9;i++){
			nbHumanPlayers.addItem(i);
		}
		
		labelNbOfCardsByPlayer = new JLabel("Number of cards by player");
		nbOfCardsByPlayer = new JComboBox();
		for(int i=8;i<16;i++){
			nbOfCardsByPlayer.addItem(i);
		}
		
		labelEndMethod = new JLabel("End method");
		endMethod = new JComboBox();
		for(EndMethod em : EndMethod.values())
			endMethod.addItem(em);

		start = new JButton("Start Game");
		cancel = new JButton("Cancel");
		this.setLayout(new GridLayout(5, 2));
		this.add(labelNbOfPlayers);
		this.add(nbPlayers);
		this.add(labelNbHumanPlayers);
		this.add(nbHumanPlayers);
		this.add(labelNbOfCardsByPlayer);
		this.add(nbOfCardsByPlayer);
		this.add(labelEndMethod);
		this.add(endMethod);
		this.add(start);
		this.add(cancel);
		
		nbPlayers.addActionListener(new NbPlayersState());
		nbHumanPlayers.addActionListener(new NbHumanPlayersState());
		nbOfCardsByPlayer.addActionListener(new NbOfCardsByPlayerState());
		endMethod.addActionListener(new EndMethodState());
		start.addActionListener(new StartState());
		cancel.addActionListener(new CancelState());
	}
	
	/**
	 * ActionListener for the cancel button
	 * @author Jeremy
	 *
	 */
	class CancelState implements ActionListener{
		public void actionPerformed(ActionEvent event){
			hideGameSettingsDialog();
		}
	}
	
	/**
	 * ActionListener for the start button
	 * @author Jeremy
	 *
	 */
	class StartState implements ActionListener{
		public void actionPerformed(ActionEvent event){
			Game.getInstance().resetPlayersList();
			boolean ok = false;
			String inputValue = null;
			for(int i=1;i<=(Integer)nbHumanPlayers.getSelectedItem();i++){
				do{
					inputValue = JOptionPane.showInputDialog(window, "Enter name for human player "+i);
					if(inputValue==null){
						ok = false;
					}
					else if(!inputValue.matches("[a-zA-Z0-9]+")){
						ok = true;
					}
					else{
						ok = false;
					}
				}while(ok);
				if(inputValue!=null)
					Game.getInstance().addHumanPlayer(inputValue);
			}
			if(inputValue!=null){
				do{
					inputValue = JOptionPane.showInputDialog(window, "Enter the target number of "+endMethod.getSelectedItem().toString());
					if(inputValue==null){
						ok = false;
					}
					else if(!inputValue.matches("[0-9]+")){
						ok = true;
					}
					else{
						ok = false;
					}
				}while(ok);
				if(inputValue!=null){
					Game.getInstance().setTarget(Integer.parseInt(inputValue));
					window.newGame();
					hideGameSettingsDialog();
				}
			}
		}
	}
	
	/**
	 * ActionListener for the number of players comboBox
	 * @author Jeremy
	 *
	 */
	class NbPlayersState implements ActionListener{
		public void actionPerformed(ActionEvent e){
			if((Integer)nbPlayers.getSelectedItem()<(Integer)nbHumanPlayers.getSelectedItem()){
				nbPlayers.setSelectedItem(nbHumanPlayers.getSelectedItem());
			}
			Game.getInstance().setNbOfPlayers((Integer)nbPlayers.getSelectedItem());
		}
	}
	
	/**
	 * ActionListener for the number of human players comboBox
	 * @author Jeremy
	 *
	 */
	class NbHumanPlayersState implements ActionListener{
		public void actionPerformed(ActionEvent e){
			if((Integer)nbPlayers.getSelectedItem()<(Integer)nbHumanPlayers.getSelectedItem()){
				nbPlayers.setSelectedItem(nbHumanPlayers.getSelectedItem());
			}
		}
	}
	
	/**
	 * ActionListener for the end methods comboBox
	 * @author Jeremy
	 *
	 */
	class EndMethodState implements ActionListener{
		public void actionPerformed(ActionEvent e){
			Game.getInstance().setEndMethod((EndMethod)endMethod.getSelectedItem());
		}
	}
	
	/**
	 * ActionListener for the number of cards by player comboBox
	 * @author Jeremy
	 *
	 */
	class NbOfCardsByPlayerState implements ActionListener{
		public void actionPerformed(ActionEvent e){
			Game.getInstance().setNbOfCardsByPlayer((Integer)nbOfCardsByPlayer.getSelectedItem());
		}
	}
	
	/**
	 * Show the dialog
	 */
	public void showGameSettingsDialog(){
		nbPlayers.setSelectedIndex(0);
		nbHumanPlayers.setSelectedIndex(0);
		endMethod.setSelectedIndex(0);
		nbOfCardsByPlayer.setSelectedIndex(0);
		this.setVisible(true);
	}
	
	/**
	 * Hide the dialog
	 */
	public void hideGameSettingsDialog(){
		this.setVisible(false);
	}
}
